package main

import (
	"flag"
	"fmt"
	"io"
	"log/slog"
	"os"

	"gopkg.in/natefinch/lumberjack.v2"
)

func initLog(logConfig *LogConfig) error {
	if logConfig.Path == "" {
		logConfig.Path = "-"
	}
	if logConfig.Level == "" {
		logConfig.Level = "INFO"
	}
	if logConfig.Format == "" {
		logConfig.Format = "text"
	}

	var lv slog.Level
	err := lv.UnmarshalText([]byte(logConfig.Level))
	if err != nil {
		return err
	}

	var out io.Writer
	if logConfig.Path == "-" {
		out = os.Stdout
	} else {
		out = &lumberjack.Logger{
			Filename:   logConfig.Path,
			MaxSize:    logConfig.MaxSize,
			MaxAge:     logConfig.MaxAge,
			MaxBackups: logConfig.MaxBackups,
			LocalTime:  logConfig.LocalTime,
			Compress:   logConfig.Compress,
		}
	}

	var h slog.Handler
	switch logConfig.Format {
	case "text":
		h = slog.NewTextHandler(out, &slog.HandlerOptions{Level: lv})
	case "json":
		h = slog.NewJSONHandler(out, &slog.HandlerOptions{Level: lv})
	default:
		return fmt.Errorf("invalid log handler %s", logConfig.Format)
	}

	slog.SetDefault(slog.New(h))

	return nil
}

func fatalf(format string, args ...any) {
	fmt.Fprintf(os.Stderr, format, args...)
	os.Exit(1)
}

func main() {
	var (
		configFile string
	)
	flag.StringVar(&configFile, "c", "./config.yaml", "configuration filename")
	flag.Parse()

	config, err := loadConfig(configFile)
	if err != nil {
		fatalf("load configuration: %v\n", err)
	}

	err = initLog(config.Log)
	if err != nil {
		fatalf("initialize log: %v\n", err)
	}

	server, err := buildServerFromConfig(config)
	if err != nil {
		fatalf("new server from configuration: %v\n", err)
	}

	err = server.listenAndServe()
	if err != nil {
		fatalf("server run: %v\n", err)
	}
}
